import { useCallback, useEffect, useMemo, useState } from "react"
import { useBrandListStore } from "../hox/brandListStore"

type BrandInfoType = undefined | false | Brand.Item
type BrandIdType = number | undefined
type showAlertType = boolean | ('sale' | 'exchange')[]
type UseBrandInfoReturnType = {
  brandInfo: BrandInfoType;
  getBrandInfoAsync: 
    (() => Promise<Exclude<BrandInfoType, undefined>>) &
    ((showAlert: showAlertType) => Promise<Exclude<BrandInfoType, undefined>>) &
    ((brandId: BrandIdType) => Promise<BrandInfoType>) &
    ((brandId: BrandIdType, showAlert: showAlertType) => Promise<Exclude<BrandInfoType, undefined>>);
}
type UseBrandInfoType =
  (() => UseBrandInfoReturnType) &
  ((showAlert: showAlertType) => UseBrandInfoReturnType) &
  ((brandId: BrandIdType) => UseBrandInfoReturnType) &
  ((brandId: BrandIdType, showAlert: showAlertType) => UseBrandInfoReturnType);

const getParams = (argument: any[]) => { 
  let brandId: BrandIdType
  let showAlert: showAlertType
  if (typeof argument[0] === 'boolean' || Array.isArray(argument[0])) {
    showAlert = argument[0]
    brandId = undefined
  } else { 
    brandId = argument[0]
    showAlert = argument[1] === undefined ? true : Boolean(argument[1])
  }
  return { brandId, showAlert }
}


const useBrandInfo: UseBrandInfoType = (...argument: any[]) => {
  const { brandId, showAlert } = getParams(argument)
  const { brandList } = useBrandListStore()

  const getBrandInfo = useCallback<(brandList: Brand.Item[], brandId: BrandIdType) => BrandInfoType>((brandList, brandId) => { 
    let res: BrandInfoType
    if (brandId !== undefined) { 
      res = brandList.find(item => item.id === brandId)
    } else res = brandList.find(item => item.brandCode === 'dianyingpiao')
    return res || false
  }, [])

  // 用于内部判断
  const brandInfo = useMemo<BrandInfoType>(() => { 
    if (!brandList) return
    return getBrandInfo(brandList, brandId)
  }, [brandList, brandId, getBrandInfo])
  // 用于外部展示
  const getReturnBrandInfo = useCallback((info: BrandInfoType, showAlert: showAlertType) => {
    if (info === undefined || info === false || typeof showAlert === 'boolean') return info
    if (showAlert.includes('sale') && info.saleStatus === 0) return false
    if (showAlert.includes('exchange') && info.exChangeStatus === 0) return false
    return info
  }, [])
  const returnBrandInfo = useMemo(() => getReturnBrandInfo(brandInfo, showAlert), [getReturnBrandInfo, brandInfo, showAlert])

  const alert = useCallback((info: BrandInfoType, show: showAlertType) => {
    if (info === undefined) return
    if (show === false) return
    return
  }, [])

  useEffect(() => { 
    if (brandInfo !== undefined) alert(brandInfo, showAlert)
  }, [brandInfo])

  // todo getBrandInfoAsync 可替换为 useAwaitAsync
  const [getBrandInfoAsyncOption, setGetBrandInfoAsyncOption] = useState<{
    callback:(res: BrandInfoType) => void;
    brandId: BrandIdType;
      }[]>([])
  
  async function getBrandInfoAsync(...argument: any[]): Promise<Exclude<BrandInfoType, undefined>> {
    const { brandId, showAlert } = getParams(argument)
    return new Promise((resolve) => { 
      const callback = (res: BrandInfoType) => { 
        alert(res, showAlert)
        resolve(getReturnBrandInfo(res, showAlert) as Exclude<BrandInfoType, undefined>)
      } 
      if (!brandList) {
        setGetBrandInfoAsyncOption(getBrandInfoAsyncOption.concat({ callback, brandId }))
      } else {
        callback(getBrandInfo(brandList, brandId))
      }
    })
  }

  useEffect(() => { 
    if (getBrandInfoAsyncOption.length && brandList) { 
      getBrandInfoAsyncOption.forEach(item => { 
        const { callback, brandId } = item
        callback(getBrandInfo(brandList, brandId))
      })
      setGetBrandInfoAsyncOption([])
    }
  }, [brandList, getBrandInfoAsyncOption])

  return {
    brandInfo: returnBrandInfo,
    getBrandInfoAsync
  }
}

export default useBrandInfo